<?php

namespace app\api\controller\wechat;

use think\Controller; // dengh quxiao
use app\api\controller\common\Wxpay;
use app\api\controller\common\SmsDemo;
use think\Db;
use think\Log;
use \think\Request;
class Jscwxapi extends Controller
{
    private $config = [
        'appid'          => 'wxe3fb920747c969c1',
        'appsecret'      => '9f2eabbf3252f822c8534d1285ffc101'
    ];

    public function getSignPackage()
    {
        $appid=$this->config['appid'];
        $url = $this->request->param('url');
        $jsapiTicket = $this->getJsApiTicket();
        $timestamp = time();
        $nonceStr = $this->createNonceStr();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=".$jsapiTicket."&noncestr=".$nonceStr."&timestamp=".$timestamp."&url=".$url;
        $signature = sha1($string);
        $signPackage = array(
            "appId" => $appid,
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return json(array('code' => '1', 'msg' => '成功','data'=>$signPackage));
    }

    private function createNonceStr($length = 16)
    {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }

    private function getJsApiTicket()
    {

        $accessToken = $this->getAccessToken();
        $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken";
        $res = json_decode($this->httpGet($url));
        $ticket = $res->ticket;
        if ($ticket) {
            return $ticket;
        }
        return false;

    }

    private function getAccessToken()
    {
        // access_token 应该全局存储与更新，以下代码以写入到文件中做示例
        $appid=$this->config['appid'];
        $appSecret=$this->config['appsecret'];
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appSecret";
        $res = json_decode($this->httpGet($url));
        $access_token = $res->access_token;
        if ($access_token) {
            return $access_token;
        }
        return false;

    }

    private function httpGet($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 500);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_URL, $url);
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    /*
     * 前端api接口
     * 换取code
     */
    public function getWxCode(){
        $post = input('post.');
        $pageUrl = isset($post['page_url']) && $post['page_url'] != '' ? $post['page_url'] : null;
        $appid=$this->config['appid'];
        $codeUrl="https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$appid."&redirect_uri=".$pageUrl."&response_type=code&scope=snsapi_userinfo&state=1&connect_redirect=1#wechat_redirect";
        return json(array('code' => '1', 'msg' => '成功','data'=>$codeUrl));
    }

    /*
     * 前端api接口
     * 获取用户openid
     */

    public function getWxOpenid(){
        $code = $this->request->param('code');
        $secret = $this->config['appsecret'];
        $appid = $this->config['appid'];;
        $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appid."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
        $res=$this->openidHttps($url);
        if(is_array($res) && $res['openid'] && $res['access_token']){
            $get_user_info_url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$res['access_token'].'&openid='.$res['openid'].'&lang=zh_CN';
            $user=$this->openidHttps($get_user_info_url);
            if(is_array($user) && $user['nickname']){
                return json(array('code' => '1', 'msg' => '成功','data'=>$res,'user'=>$user));
            }else{
                return json(array('code' => '0', 'msg' => '失败'));
            }
        }else{
            return json(array('code' => '0', 'msg' => '失败'));
        }


    }

    public function openidHttps($url){
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_TIMEOUT,30);

        $content = curl_exec($ch);
        $status = (int)curl_getinfo($ch,CURLINFO_HTTP_CODE);
        if ($status == 404) {
            return $status;
        }
        curl_close($ch);
        return json_decode($content,true);
    }

    //重新刷新获取access_token
    public function refreshToken(){
        $appid = $this->config['appid'];
        $secret = $this->config['appsecret'];
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$secret;
        $ch = curl_init();
        curl_setopt($ch,CURLOPT_URL,$url);
        curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
        curl_setopt($ch,CURLOPT_TIMEOUT,30);

        $content = curl_exec($ch);
        $status = (int)curl_getinfo($ch,CURLINFO_HTTP_CODE);
        if ($status == 404) {
            return $status;
        }
        curl_close($ch);
        return json_decode($content,true);
    }

    public function getChannelUrl(){
        $post = input('post.');
        $hostname = isset($post['hostname']) && $post['hostname'] != '' ? $post['hostname'] : null;
        if(!$hostname){
            return json(array('code' => '0', 'msg' => '参数错误'));
        }
        $where['url'] = ['like', '%' . $hostname . '%'];
        $where['is_delete'] = 0;
        $res=db('zsqudao')->where($where)->select();
        if(is_array($res) && count($res)>0){
            return json(array('code' => '1', 'msg' => '成功','data' => $res[0]['url']));
        }else{
            return json(array('code' => '2', 'msg' => '暂无预登记链接'));
        }
    }

    public function getTabName($exhibition_id){
        $result=db('exhibition')->where(['id'=>$exhibition_id])->find();
        $tabName='';
        if($result){
            $tabName=$result['create_person_table'];
        }else{
            return json(['code'=>0,'msg'=>'缺少关键字段','data'=>'']);
        }
        return $tabName;
    }

    //生成订单，调起支付
    public function newpay()
    {
        Db::startTrans();
        try {
            $post = input('post.');
            $id = isset($post['id']) && $post['id'] != '' ? $post['id'] : 0;
            $basePerson=db('company_user')->where(['id'=>$id])->find();
            if(!$basePerson){
                return json(['code'=>0,'msg'=>'人员信息查询错误']);
            }
            $exhibition_id = isset($post['exhibition_id']) && $post['exhibition_id'] != '' ? $post['exhibition_id'] : 0;
            $exhibition=db('exhibition')->where(['is_delete'=>0,'id'=>$exhibition_id])->find();
            if(!$exhibition){
                return json(['code'=>0,'msg'=>'展会信息错误']);
            }
            if(!$exhibition['appid']){
                return json(['code'=>0,'msg'=>'公众号appid错误']);
            }
            $tabName=$this->getTabName($exhibition_id);
            $person=db($tabName)->where(['person_id'=>$id])->find();
            if(!$person){
                return json(['code'=>0,'msg'=>'公海信息查询错误']);
            }
            $openid = isset($post['openid']) && $post['openid'] != '' ? $post['openid'] : null;
            if(!$openid){
                return json(['code'=>0,'msg'=>'人员信息查询错误']);
            }

            #开始订单查询
            $total_fee = $exhibition['ticket_amount'];//门票金额
            $playStatus=true;
            if(!$total_fee || $total_fee<=0){
                return json(['code'=>0,'msg'=>'门票金额查询错误']);
            }
            $card_voucher = isset($post['card_voucher']) && $post['card_voucher'] != '' ? $post['card_voucher'] : null;
            if($card_voucher){
                $channel_id = isset($post['channel_id']) && $post['channel_id'] != '' ? $post['channel_id'] : 0;
                $channel=db('zsqudao')->where(['id'=>$channel_id,'is_delete'=>0])->find();
                if(!$channel){
                    return json(['code'=>0,'msg'=>'卡券信息错误']);
                }
                $card_amount = $channel['card_amount'];//卡卷金额
                $ready_card_voucher = $channel['card_voucher'];//卡卷号码
                if($card_voucher==$ready_card_voucher){
                    $total_fee=$total_fee-$card_amount;
                    if($total_fee<0){
                        return json(['code'=>0,'msg'=>'门票优惠金额查询错误']);
                    }
                    if($total_fee==0){
                        $playStatus=false;
                    }
                }else{
                    return json(['code'=>0,'msg'=>'优惠劵码查询错误']);
                }
            }


            $pay_sn = date('YmdHis').rand(1000,9999);
            $order=db('company_user_order')->where(['exhibition_id'=>$exhibition_id,'openid'=>$openid,'is_delete'=>0])->find();
            if($order && $order['order_num']){
                if($order['wx_order_num'] || $order['status']==1){
                    return json(['code'=>'2','msg'=>'您的订单已支付,无需重复支付']);
                }
                $pay_sn=$order['order_num'];
            }else{
                $data['order_num']=$pay_sn;
                $data['create_time']=time();
                $data['update_time']=time();
                $data['exhibition_id']=$exhibition_id;
                $data['public_user_id']=$id;
                $data['user_id']=$person['id'];
                $data['openid']=$openid;
                $data['appid']=$exhibition['appid'];
                $data['card_voucher']=$card_voucher;
                if($playStatus===false){
                    $data['status']=1;
                    $data['wx_order_num']=$pay_sn;
                    $data['total_fee']='0.00';
                    $data['play_time']=time();;
                }
                $r = db('company_user_order')->lock(true)->insert($data);
                if(false === $r){
                    Db::rollback();
                    return json(['code'=>'0','msg'=>'订单生成失败']);
                }
                db($tabName)->where(['id'=>$person['id']])->update(['examine_type'=>1]);
                if($playStatus===false){
                    $this->smsPhone($person,$exhibition_id);
                    Db::commit();
                    return json(['code'=>'3','msg'=>'支付成功']);
                }
            }
//            $total_fee='0.01';
            $body   = $exhibition['title']."参观门票";
            $notify_url = "https://crmapi.plfasia.com/index.php/api/wechat/Jscwxapi/notify";  #根据不同类型回调地址不同
            $trade_type = 'JSAPI';
            #JSAPI--JSAPI支付（或小程序支付）、
            #NATIVE--Native支付、
            #APP--app支付，
            #MWEB--H5支付，
            #不同trade_type决定了调起支付的方式，请根据支付产品正确上传
            #新的需要参数为六个
            # out_trade_no 商户订单号
            # total_fee    订单总额
            # body         商品描述
            # spbill_create_ip   终端IP
            # notify_url   回调通知地址
            # trade_type   交易类型

            $wxpay  = new Wxpay();
            $request = Request::instance();
            $date = [
                'out_trade_no'  => $pay_sn,
                'total_fee'     => $total_fee,
                'body'          => $body,
                'spbill_create_ip' => $request->ip(),
                'notify_url' => $notify_url,
                'trade_type' => $trade_type
            ];
            #根据 trade_type  类型不同，是否传递openid

            #APP   类型支付调用
//            $res = $wxpay->index($date);

            #JSAPI 类型支付调用
            $res = $wxpay->index($date,$openid);
            #获得后将对应内容返回前端即可
            Db::commit();
            return json(array('code' => '1', 'msg' => '成功','data'=>$res));
        } catch (\Exception $e) {
            Db::rollback();
            return json(array('code' => '0', 'msg' => $e->getMessage()));
        }
    }

    public function smsPhone($data,$exhibition_id){
        $phoneData=array('is_cart'=>$data['is_cart'],'userName'=>($data['name_cn']?$data['name_cn']:($data['name_en']?$data['name_en']:'预登记观众')));
        $phone_tmp=db('email_sms')->where(['type'=>0,'sms_type'=>2,'exhibition_id'=>$exhibition_id,'is_delete'=>0])->find();
        if($phone_tmp){
            $SmsDemo=new SmsDemo();
            $SmsDemo->sendSms($data['mobile_person'],$phone_tmp['sms_autograph'],$phone_tmp['sms_code'],$phoneData);
        }
        return true;
    }


    public function getOderDetail(){
        $post = input('post.');
        $id = isset($post['id']) && $post['id'] != '' ? $post['id'] : 0;
        $basePerson=db('company_user')->where(['id'=>$id])->find();
        if(!$basePerson){
            return json(['code'=>1,'msg'=>'基础信息查询错误']);
        }
        $exhibition_id = isset($post['exhibition_id']) && $post['exhibition_id'] != '' ? $post['exhibition_id'] : 0;
        $exhibition=db('exhibition')->where(['is_delete'=>0,'id'=>$exhibition_id])->find();
        if(!$exhibition){
            return json(['code'=>0,'msg'=>'展会信息错误']);
        }
        $tabName=$this->getTabName($exhibition_id);
        $person=db($tabName)->where(['person_id'=>$id])->find();
        if(!$person){
            return json(['code'=>1,'msg'=>'公海信息查询错误']);
        }
        $openid = isset($post['openid']) && $post['openid'] != '' ? $post['openid'] : null;
        if(!$openid){
            return json(['code'=>1,'msg'=>'信息查询错误']);
        }
        $order=db('company_user_order')->where(['exhibition_id'=>$exhibition_id,'openid'=>$openid,'is_delete'=>0])->find();
        return json(['code'=>1,'msg'=>'成功','order'=>$order,'detail'=>$person]);
    }


    public function notify()
    {
        $xmlstr = file_get_contents("php://input");
        if(empty($xmlstr)){
            $data['create_time']=time();
            $data['text']='非法访问';
            db('user_wxpay')->insert($data);
            return 'fail';
        }
        $xmlObj = simplexml_load_string($xmlstr, 'SimpleXMLElement', LIBXML_NOCDATA);
        $wxpay = json_decode(json_encode($xmlObj),true);
        if ($this->checkSign($wxpay)) {
            $data['create_time']=time();
            $data['text']=json_encode($xmlObj);
            db('user_wxpay')->insert($data);
            $openid = $wxpay['openid'];
            $appid = $wxpay['appid'];
            $total_fee = $wxpay['total_fee'];
            $wx_order_num = $wxpay['out_trade_no'];
            $res=db('company_user_order')->where(['openid'=>$openid,'appid'=>$appid])->update(['status'=>1,'wx_order_num'=>$wx_order_num,'total_fee'=>$total_fee,'play_time'=>time()]);
            if($res){
                $orderBase=db('company_user_order')->where(['openid'=>$openid,'appid'=>$appid])->find();
                if($orderBase){
                    $tabName=$this->getTabName($orderBase['exhibition_id']);
                    $person=db($tabName)->where(['person_id'=>$orderBase['user_id']])->find();
                    if($person){
                        $this->smsPhone($person,$orderBase['exhibition_id']);
                    }
                }

                $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
                echo $str;
            }
            return 'success';
        }
        $data['create_time']=time();
        $data['text']='支付验证有误';
        db('user_wxpay')->insert($data);
        $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[支付验证有误]]></return_msg></xml>';
        echo $str;
        return 'fail';
    }

    private function checkSign($arr)
    {
        $sign = $arr['sign'];
        unset($arr['sign']);
        $key='aRFHGFHhrwR2yRHN326pmXiYpNtHNS5R';//微信商户平台支付设置的key
        ksort($arr);//根据key升序排序
        $str=http_build_query($arr);//数组字典排序拼接字符串
        $stringSignTemp = $str.'&key='.$key;//拼接上key
        $signValue = md5($stringSignTemp);//md5处理
        $signValue = strtoupper($signValue);//转大写
        return $signValue == $sign;

    }



    //获取展会数据
    public function getExhibition()
    {
        if (request()->isPost()) {
            $resList = db('exhibition')
                ->alias('h')
                ->field('h.*,q.card_voucher as ch_card_voucher,q.card_amount as ch_card_amount')
                ->join('zsqudao q','q.id=h.wechat_channel_id','left')
                ->where(['h.is_delete' => 0,'h.project_id'=>25,'h.is_wechat'=>1])
                ->order('h.id desc')
                ->select();
            foreach ($resList as &$val) {
                $val['title']=$val['wechat_name'];
            }
            return json(array('code' => '1', 'msg' => '成功', 'data' => $resList));
        } else {
            return json(array('code' => '0', 'msg' => '请求失败'));
        }
    }

    public function ticketAmountDetail(){
        if (request()->isPost()) {
            $post = input('post.');
            $exhibition_id = isset($post['exhibition_id']) && $post['exhibition_id'] != '' ? $post['exhibition_id'] : 0;
            $exhibition = db('exhibition')->where(['is_delete' => 0, 'id' => $exhibition_id])->find();
            if (!$exhibition) {
                return json(['code' => 0, 'msg' => '展会信息错误']);
            }
            $channel_id = isset($post['channel_id']) && $post['channel_id'] != '' ? $post['channel_id'] : 0;
            $res = db('zsqudao')->where(['id' => $channel_id, 'is_delete' => 0, 'exhibition_id' => $exhibition_id])->find();
            if ($res) {
                $res['ticket_amount'] = $exhibition['ticket_amount'];
            }
            return json(array('code' => '1', 'msg' => '成功', 'data' => $res));
        }else {
            return json(array('code' => '0', 'msg' => '请求失败'));
        }

    }


    /*
     * 机车小程序接口
     * 获取活动详情及报名信息
     */
    public function activeDetail(){
        if (request()->isPost()) {
            $post = input('post.');
            $exhibition_id = isset($post['exhibition_id']) && $post['exhibition_id'] != '' ? $post['exhibition_id'] : 0;
            $exhibition = db('exhibition')->where(['is_delete' => 0, 'id' => $exhibition_id])->find();
            if (!$exhibition) {
                return json(['code' => 0, 'msg' => '展会信息错误']);
            }
            $id = isset($post['id']) && $post['id'] != '' ? $post['id'] : 0;
            $res = db('zh_active')->where(['id' => $id, 'exhibition_id' => $exhibition_id])->find();
            if (!$res) {
                return json(['code' => 0, 'msg' => '活动信息错误']);
            }
            $phone = isset($post['phone']) && $post['phone'] != '' ? $post['phone'] : null;
            if(!$phone){
                return json(['code' => 0, 'msg' => '电话号码信息错误']);
            }
            $sing=db('zh_active_signup')->where(['active_id'=>$id,'exhibition_id'=>$exhibition_id,'mobile_person'=>$phone])->find();
            return json(array('code' => '1', 'msg' => '成功', 'data' => $res,'is_singUp'=>(!empty($sing)?1:0)));
        }else {
            return json(array('code' => '0', 'msg' => '请求失败'));
        }
    }

    /*
     * 机车小程序接口
     * 获取活动报名信息
     */
    public function activeSing(){
        if (request()->isPost()) {
            $post = input('post.');
            $exhibition_id = isset($post['exhibition_id']) && $post['exhibition_id'] != '' ? $post['exhibition_id'] : 0;
            $exhibition = db('exhibition')->where(['is_delete' => 0, 'id' => $exhibition_id])->find();
            if (!$exhibition) {
                return json(['code' => 0, 'msg' => '展会信息错误']);
            }
            $phone = isset($post['phone']) && $post['phone'] != '' ? $post['phone'] : null;
            if(!$phone){
                return json(['code' => 0, 'msg' => '电话号码信息错误']);
            }
            $list = Db::name('zh_active_signup')
                ->alias('pc')
                ->field('pc.active_id,s.*')
                ->join('zh_active s','s.id=pc.active_id','left')
                ->where(['pc.exhibition_id'=>$exhibition_id,'pc.mobile_person'=>$phone])->order('pc.create_time desc')
                ->select();
            return json(array('code' => '1', 'msg' => '成功', 'data' => $list));
        }else {
            return json(array('code' => '0', 'msg' => '请求失败'));
        }
    }
}
